{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e62931a-04ac-4be5-a1dc-0ead5c992b0c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看数据文件目录  list datalab files\n",
    "!ls datalab/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b8e36ea-ec31-4a1f-9b8f-ecba0ba669f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 基础工具\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import warnings\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from scipy.special import jn\n",
    "from IPython.display import display, clear_output\n",
    "import time\n",
    "\n",
    "warnings.filterwarnings('ignore')\n",
    "%matplotlib inline\n",
    "\n",
    "## 模型预测的\n",
    "from sklearn import linear_model\n",
    "from sklearn import preprocessing\n",
    "from sklearn.svm import SVR\n",
    "from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor\n",
    "\n",
    "## 数据降维处理的\n",
    "from sklearn.decomposition import PCA,FastICA,FactorAnalysis,SparsePCA\n",
    "\n",
    "import lightgbm as lgb\n",
    "import xgboost as xgb\n",
    "\n",
    "## 参数搜索和评价的\n",
    "from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold,train_test_split\n",
    "from sklearn.metrics import mean_squared_error, mean_absolute_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b69164d8-7437-4b2f-bab4-085e1434512c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# 显示当前工作目录\n",
    "print(\"Current Working Directory:\", os.getcwd())\n",
    "\n",
    "# 列出当前工作目录中的所有文件和文件夹\n",
    "print(\"Files and directories in current working directory:\")\n",
    "print(os.listdir())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7116ddb9-74fd-4da3-b3f4-2b6761f7ab51",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 通过Pandas对于数据进行读取 (pandas是一个很友好的数据读取函数库)\n",
    "Train_data = pd.read_csv('/mnt/workspace/used_car_train_20200313.csv', sep=' ')\n",
    "TestA_data = pd.read_csv('/mnt/workspace/used_car_testA_20200313.csv', sep=' ')\n",
    "\n",
    "## 输出数据的大小信息\n",
    "print('Train data shape:',Train_data.shape)\n",
    "print('TestA data shape:',TestA_data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10211a88-aa63-4896-8d34-a0a894d0b1ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 通过.head() 简要浏览读取数据的形式\n",
    "Train_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7f4d4084-ac59-4a83-89a0-99250833c24b",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 通过 .info() 简要可以看到对应一些数据列名，以及NAN缺失信息\n",
    "Train_data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bc38314-8871-407b-9dad-5b466a98dfdf",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 通过 .columns 查看列名\n",
    "Train_data.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c4995aa-0032-4cce-8548-7d63d8bfccbb",
   "metadata": {},
   "outputs": [],
   "source": [
    "TestA_data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4decf9ad-3605-4b54-9855-f2b5e14711f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 通过 .describe() 可以查看数值特征列的一些统计信息\n",
    "Train_data.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7e5e1d9-088f-49f1-ae7d-c7f570746698",
   "metadata": {},
   "outputs": [],
   "source": [
    "TestA_data.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "620f235c-e693-482b-aeee-a0bce2325a84",
   "metadata": {},
   "outputs": [],
   "source": [
    "numerical_cols = Train_data.select_dtypes(exclude = 'object').columns\n",
    "print(numerical_cols)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46a45984-d8c0-41fd-b545-f032fb4c0625",
   "metadata": {},
   "outputs": [],
   "source": [
    "categorical_cols = Train_data.select_dtypes(include = 'object').columns\n",
    "print(categorical_cols)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8117171-2ad4-4f51-bcab-e9f31165c253",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 选择特征列\n",
    "feature_cols = [col for col in numerical_cols if col not in ['SaleID','name','regDate','creatDate','price','model','brand','regionCode','seller']]\n",
    "feature_cols = [col for col in feature_cols if 'Type' not in col]\n",
    "\n",
    "## 提前特征列，标签列构造训练样本和测试样本\n",
    "X_data = Train_data[feature_cols]\n",
    "Y_data = Train_data['price']\n",
    "\n",
    "X_test  = TestA_data[feature_cols]\n",
    "\n",
    "print('X train shape:',X_data.shape)\n",
    "print('X test shape:',X_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "729fbc96-fa7a-446d-b267-3070c0cb4583",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 定义了一个统计函数，方便后续信息统计\n",
    "def Sta_inf(data):\n",
    "    print('_min',np.min(data))\n",
    "    print('_max:',np.max(data))\n",
    "    print('_mean',np.mean(data))\n",
    "    print('_ptp',np.ptp(data))\n",
    "    print('_std',np.std(data))\n",
    "    print('_var',np.var(data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ae27995f-970b-4f98-99e8-5690afb99dcd",
   "metadata": {},
   "outputs": [],
   "source": [
    "print('Sta of label:')\n",
    "Sta_inf(Y_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c956ced6-b252-4a61-8f0a-e948233fdee7",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 绘制标签的统计图，查看标签分布\n",
    "plt.hist(Y_data)\n",
    "plt.show()\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87cae595-f6dc-4cd0-98d4-5852da1f55e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_data = X_data.fillna(-1)\n",
    "X_test = X_test.fillna(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ae70217-d2da-4942-a35e-24d9e762fcc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "## xgb-Model\n",
    "xgr = xgb.XGBRegressor(n_estimators=120, learning_rate=0.1, gamma=0, subsample=0.8,\\\n",
    "        colsample_bytree=0.9, max_depth=7) #,objective ='reg:squarederror'\n",
    "\n",
    "scores_train = []\n",
    "scores = []\n",
    "\n",
    "## 5折交叉验证方式\n",
    "sk=StratifiedKFold(n_splits=5,shuffle=True,random_state=0)\n",
    "for train_ind,val_ind in sk.split(X_data,Y_data):\n",
    "    \n",
    "    train_x=X_data.iloc[train_ind].values\n",
    "    train_y=Y_data.iloc[train_ind]\n",
    "    val_x=X_data.iloc[val_ind].values\n",
    "    val_y=Y_data.iloc[val_ind]\n",
    "    \n",
    "    xgr.fit(train_x,train_y)\n",
    "    pred_train_xgb=xgr.predict(train_x)\n",
    "    pred_xgb=xgr.predict(val_x)\n",
    "    \n",
    "    score_train = mean_absolute_error(train_y,pred_train_xgb)\n",
    "    scores_train.append(score_train)\n",
    "    score = mean_absolute_error(val_y,pred_xgb)\n",
    "    scores.append(score)\n",
    "\n",
    "print('Train mae:',np.mean(score_train))\n",
    "print('Val mae',np.mean(scores))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "61fb1117-97ad-4023-94b2-68abe0084399",
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_model_xgb(x_train,y_train):\n",
    "    model = xgb.XGBRegressor(n_estimators=150, learning_rate=0.1, gamma=0, subsample=0.8,\\\n",
    "        colsample_bytree=0.9, max_depth=7) #, objective ='reg:squarederror'\n",
    "    model.fit(x_train, y_train)\n",
    "    return model\n",
    "\n",
    "def build_model_lgb(x_train,y_train):\n",
    "    estimator = lgb.LGBMRegressor(num_leaves=127,n_estimators = 150)\n",
    "    param_grid = {\n",
    "        'learning_rate': [0.01, 0.05, 0.1, 0.2],\n",
    "    }\n",
    "    gbm = GridSearchCV(estimator, param_grid)\n",
    "    gbm.fit(x_train, y_train)\n",
    "    return gbm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be3d1623-0699-4344-8f8a-e243f4a919f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "## Split data with val\n",
    "x_train,x_val,y_train,y_val = train_test_split(X_data,Y_data,test_size=0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ea6c01e-d02f-47e7-8a68-811a732ecb47",
   "metadata": {},
   "outputs": [],
   "source": [
    "print('Train lgb...')\n",
    "model_lgb = build_model_lgb(x_train,y_train)\n",
    "val_lgb = model_lgb.predict(x_val)\n",
    "MAE_lgb = mean_absolute_error(y_val,val_lgb)\n",
    "print('MAE of val with lgb:',MAE_lgb)\n",
    "\n",
    "print('Predict lgb...')\n",
    "model_lgb_pre = build_model_lgb(X_data,Y_data)\n",
    "subA_lgb = model_lgb_pre.predict(X_test)\n",
    "print('Sta of Predict lgb:')\n",
    "Sta_inf(subA_lgb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3020fec7-6bcf-468a-b5a9-12ffdf9f049d",
   "metadata": {},
   "outputs": [],
   "source": [
    "print('Train xgb...')\n",
    "model_xgb = build_model_xgb(x_train,y_train)\n",
    "val_xgb = model_xgb.predict(x_val)\n",
    "MAE_xgb = mean_absolute_error(y_val,val_xgb)\n",
    "print('MAE of val with xgb:',MAE_xgb)\n",
    "\n",
    "print('Predict xgb...')\n",
    "model_xgb_pre = build_model_xgb(X_data,Y_data)\n",
    "subA_xgb = model_xgb_pre.predict(X_test)\n",
    "print('Sta of Predict xgb:')\n",
    "Sta_inf(subA_xgb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "baf6d6da-9d82-4167-8067-35bd541f895e",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 这里我们采取了简单的加权融合的方式\n",
    "val_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*val_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*val_xgb\n",
    "val_Weighted[val_Weighted<0]=10 # 由于我们发现预测的最小值有负数，而真实情况下，price为负是不存在的，由此我们进行对应的后修正\n",
    "print('MAE of val with Weighted ensemble:',mean_absolute_error(y_val,val_Weighted))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "40b45a79-d84b-4734-bfab-dca4dd2d2749",
   "metadata": {},
   "outputs": [],
   "source": [
    "sub_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*subA_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*subA_xgb\n",
    "\n",
    "## 查看预测值的统计进行\n",
    "plt.hist(Y_data)\n",
    "plt.show()\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a1122693-b5c6-4aa3-a7e2-e93984bd0415",
   "metadata": {},
   "outputs": [],
   "source": [
    "sub = pd.DataFrame()\n",
    "sub['SaleID'] = TestA_data.SaleID\n",
    "sub['price'] = sub_Weighted\n",
    "sub.to_csv('./sub_Weighted.csv',index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94ae430b-f596-4ed8-8214-399993ed2160",
   "metadata": {},
   "outputs": [],
   "source": [
    "sub.head()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
